#include <iostream>

//定义展开行数
const int LINE = 1;
//取余子式
double *GetMinor(double *p, int n, int x, int y);
//求二阶行列式
double CountDet(double *p);
//按第一行展开行列式
double UnfoldDet_FirstLine(double *p, int n);
//获取行列式
double *GetDet(int n);
int main(void)
{
	using std::cout;
	using std::cin;
	using std::endl;

	int level;


	//获取行列式的阶数
	cout << "输入行列式阶数:";
	cin >> level;
	//清除回车
	cin.get();

	//处理简单情况
	if (level <= 0)
	{
		cout  << "这我不会算啊。。。" << endl;
	}
	else if (level == 1)
	{
		double *n = new double;
		cin >> *n;
		cout << "行列式的值为: " << *n << endl;
		delete n;
	}
	else if (level == 2)
	{
		double *Det = GetDet(level);
		
		cout << "行列式的值为: " << CountDet(Det) << endl;

		delete [] Det;
	}
	else
	{
		double *Det = GetDet(level);
		
		
		cout << "行列式的值为: " << UnfoldDet_FirstLine(Det, level) << endl;
	
		delete [] Det;
	}
	
	return 0;
}

//获取行列式
double *GetDet(int n)
{
	using std::cin;

	double *p = new double[n*n];

	for (int i = 0; i < n; i++)
		for (int j = i * n; j <(i * n) + n; j++)
			cin >> p[j];

	return p;
}

//取余子式
double *GetMinor(double *p, int n, int x, int y)
{
	double *Minor = new double[(n - 1)*(n - 1)];
	int line = 0, train = 0;
	
	for (int i = 0; i < n; i++)
	{
		if (i != (y - 1))
		{	
			for (int j = i * n; j < (i * n) + n; j++)
				if (j != (i * n) + (x - 1))
				{
					Minor[line * (n - 1) + train] = p[j];
			
					train++;
				}
	
			train = 0;
			line++;
	
		}
	}

	return Minor;
}


//求二阶行列式
double CountDet(double *p)
{
	return (p[0]*p[3] - p[1]*p[2]);
}


//按第一行展开行列式
double UnfoldDet_FirstLine(double *p, int n)
{
	if (n == 3)
	{
		double temp = 0;
		
		double *clear;  //用于delete

		for (int i = 1; i <= n; i++)
		{
			if ((i + 1) % 2 != 0)
				temp += p[i - 1] * (-1) * CountDet(clear = GetMinor(p, n, i, LINE));
			else
				temp += p[i - 1] * CountDet(clear = GetMinor(p, n, i, LINE)); 
			
			delete [] clear;
		}

		return temp;
	}
	else
	{
		double temp = 0;

		double *clear;  //用于delete

		for (int i = 1; i <= n; i++)
		{
			if ((i + 1) % 2 != 0)
				temp += p[i - 1] * (-1) * UnfoldDet_FirstLine(clear = GetMinor(p, n, i, LINE), n - 1);
			else
				temp += p[i - 1] * UnfoldDet_FirstLine(clear = GetMinor(p, n, i, LINE), n - 1);
		
			delete [] clear;
		}

		return temp;
	}
}
